home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / hplip / check.py < prev    next >
Encoding:
Python Source  |  2009-04-14  |  29.4 KB  |  851 lines

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # (c) Copyright 2003-2009 Hewlett-Packard Development Company, L.P.
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program; if not, write to the Free Software
  18. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  19. #
  20. # Author: Don Welch
  21. #
  22.  
  23. __version__ = '14.1'
  24. __title__ = 'Dependency/Version Check Utility'
  25. __mod__ = 'hp-check'
  26. __doc__ = """Check the existence and versions of HPLIP dependencies. (Run as 'python ./check.py' from the HPLIP tarball before installation.)"""
  27.  
  28. # Std Lib
  29. import sys
  30. import os
  31. import getopt
  32. import commands
  33. import re
  34.  
  35. # Local
  36. from base.g import *
  37. from base import utils, tui, models
  38. from installer import dcheck
  39. from installer.core_install import *
  40.  
  41. device_avail = False
  42. try:
  43.     from base import device, pml
  44.     # This can fail due to hpmudext not being present
  45. except ImportError:
  46.     log.debug("Device library is not avail.")
  47. else:
  48.     device_avail = True
  49.  
  50.  
  51. USAGE = [(__doc__, "", "name", True),
  52.          ("Usage: %s [OPTIONS]" % __mod__, "", "summary", True),
  53.          utils.USAGE_OPTIONS,
  54.          ("Compile-time check:", "-c or --compile", "option", False),
  55.          ("Run-time check:", "-r or --run", "option", False),
  56.          ("Compile and run-time checks:", "-b or --both (default)", "option", False),
  57.          utils.USAGE_LOGGING1, utils.USAGE_LOGGING2, utils.USAGE_LOGGING3,
  58.          utils.USAGE_LOGGING_PLAIN,
  59.          utils.USAGE_HELP,
  60.          utils.USAGE_NOTES,
  61.          ("1. For checking for the proper build environment for the HPLIP supplied tarball (.tar.gz or .run),", "", "note", False),
  62.          ("use the --compile or --both switches.", "", "note", False),
  63.          ("2. For checking for the proper runtime environment for a distro supplied package (.deb, .rpm, etc),", "", "note", False),
  64.          ("use the --runtime switch.", "", "note", False),
  65.         ]
  66.  
  67. def usage(typ='text'):
  68.     if typ == 'text':
  69.         utils.log_title(__title__, __version__)
  70.  
  71.     utils.format_text(USAGE, typ, __title__, __mod__, __version__)
  72.     sys.exit(0)
  73.  
  74.  
  75. build_str = "HPLIP will not build, install, and/or function properly without this dependency."
  76.  
  77. pat_deviceuri = re.compile(r"""(.*):/(.*?)/(\S*?)\?(?:serial=(\S*)|device=(\S*)|ip=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}[^&]*))(?:&port=(\d))?""", re.I)
  78.  
  79. pat_cups_error_log = re.compile("""^loglevel\s?(debug|debug2|warn|info|error|none)""", re.I)
  80.  
  81.  
  82. def parseDeviceURI(device_uri):
  83.     m = pat_deviceuri.match(device_uri)
  84.  
  85.     if m is None:
  86.         raise Error(ERROR_INVALID_DEVICE_URI)
  87.  
  88.     back_end = m.group(1).lower() or ''
  89.     is_hp = (back_end in ('hp', 'hpfax', 'hpaio'))
  90.     bus = m.group(2).lower() or ''
  91.  
  92.     if bus not in ('usb', 'net', 'bt', 'fw', 'par'):
  93.         raise Error(ERROR_INVALID_DEVICE_URI)
  94.  
  95.     model = m.group(3) or ''
  96.     serial = m.group(4) or ''
  97.     dev_file = m.group(5) or ''
  98.     host = m.group(6) or ''
  99.     port = m.group(7) or 1
  100.  
  101.     if bus == 'net':
  102.         try:
  103.             port = int(port)
  104.         except (ValueError, TypeError):
  105.             port = 1
  106.  
  107.         if port == 0:
  108.             port = 1
  109.  
  110.     return back_end, is_hp, bus, model, serial, dev_file, host, port
  111.  
  112. num_errors = 0
  113. fmt = True
  114. overall_commands_to_run = []
  115. time_flag = DEPENDENCY_RUN_AND_COMPILE_TIME
  116.  
  117. try:
  118.     log.set_module(__mod__)
  119.  
  120.     try:
  121.         opts, args = getopt.getopt(sys.argv[1:], 'hl:gtcrb',
  122.             ['help', 'help-rest', 'help-man', 'help-desc', 'logging=',
  123.              'run', 'runtime', 'compile', 'both'])
  124.  
  125.     except getopt.GetoptError, e:
  126.         log.error(e.msg)
  127.         usage()
  128.         sys.exit(1)
  129.  
  130.     if os.getenv("HPLIP_DEBUG"):
  131.         log.set_level('debug')
  132.  
  133.     log_level = 'info'
  134.  
  135.     for o, a in opts:
  136.         if o in ('-h', '--help'):
  137.             usage()
  138.  
  139.         elif o == '--help-rest':
  140.             usage('rest')
  141.  
  142.         elif o == '--help-man':
  143.             usage('man')
  144.  
  145.         elif o == '--help-desc':
  146.             print __doc__,
  147.             sys.exit(0)
  148.  
  149.         elif o in ('-l', '--logging'):
  150.             log_level = a.lower().strip()
  151.  
  152.         elif o == '-g':
  153.             log_level = 'debug'
  154.  
  155.         elif o == '-t':
  156.             fmt = False
  157.  
  158.         elif o in ('-c', '--compile'):
  159.             time_flag = DEPENDENCY_COMPILE_TIME
  160.  
  161.         elif o in ('-r', '--runtime', '--run'):
  162.             time_flag = DEPENDENCY_RUN_TIME
  163.  
  164.         elif o in ('-b', '--both'):
  165.             time_flag = DEPENDENCY_RUN_AND_COMPILE_TIME
  166.  
  167.     if not log.set_level(log_level):
  168.         usage()
  169.  
  170.     if not fmt:
  171.         log.no_formatting()
  172.  
  173.     utils.log_title(__title__, __version__)
  174.  
  175.     log.info(log.bold("Note: hp-check can be run in three modes:"))
  176.  
  177.     for l in tui.format_paragraph("1. Compile-time check mode (-c or --compile): Use this mode before compiling the HPLIP supplied tarball (.tar.gz or .run) to determine if the proper dependencies are installed to successfully compile HPLIP."):
  178.         log.info(l)
  179.  
  180.     for l in tui.format_paragraph("2. Run-time check mode (-r or --run): Use this mode to determine if a distro supplied package (.deb, .rpm, etc) or an already built HPLIP supplied tarball has the proper dependencies installed to successfully run."):
  181.         log.info(l)
  182.  
  183.     for l in tui.format_paragraph("3. Both compile- and run-time check mode (-b or --both) (Default): This mode will check both of the above cases (both compile- and run-time dependencies)."):
  184.         log.info(l)
  185.  
  186.     log.info()
  187.  
  188.     log_file = os.path.normpath('./hp-check.log')
  189.     log.info(log.bold("Saving output in log file: %s" % log_file))
  190.     log.debug("Log file=%s" % log_file)
  191.     if os.path.exists(log_file):
  192.         os.remove(log_file)
  193.  
  194.     log.set_logfile(log_file)
  195.     log.set_where(log.LOG_TO_CONSOLE_AND_FILE)
  196.  
  197.     log.info("\nInitializing. Please wait...")
  198.     core =  CoreInstall(MODE_CHECK)
  199.     core.init()
  200.     core.set_plugin_version()
  201.  
  202.     tui.header("SYSTEM INFO")
  203.  
  204.     log.info(log.bold("Basic system information:"))
  205.     log.info(core.sys_uname_info)
  206.  
  207.     log.info()
  208.     log.info(log.bold("Distribution:"))
  209.     log.info("%s %s" % (core.distro_name, core.distro_version))
  210.  
  211.     log.info(log.bold("\nHPOJ running?"))
  212.  
  213.     if core.hpoj_present:
  214.         log.error("Yes, HPOJ is running. HPLIP is not compatible with HPOJ. To run HPLIP, please remove HPOJ.")
  215.         num_errors += 1
  216.     else:
  217.         log.info("No, HPOJ is not running (OK).")
  218.  
  219.  
  220.     log.info()
  221.     log.info(log.bold("Checking Python version..."))
  222.     ver = sys.version_info
  223.     log.debug("sys.version_info = %s" % repr(ver))
  224.     ver_maj = ver[0]
  225.     ver_min = ver[1]
  226.     ver_pat = ver[2]
  227.  
  228.     if ver_maj == 2:
  229.         if ver_min >= 1:
  230.             log.info("OK, version %d.%d.%d installed" % ver[:3])
  231.         else:
  232.             log.error("Version %d.%d.%d installed. Please update to Python >= 2.1" % ver[:3])
  233.             sys.exit(1)
  234.  
  235.  
  236.     if core.ui_toolkit == 'qt3':
  237.  
  238.         log.info()
  239.         log.info(log.bold("Checking PyQt 3.x version..."))
  240.  
  241.         # PyQt 3
  242.         try:
  243.             import qt
  244.         except ImportError:
  245.             num_errors += 1
  246.             log.error("NOT FOUND OR FAILED TO LOAD!")
  247.         else:
  248.             # check version of Qt
  249.             qtMajor = int(qt.qVersion().split('.')[0])
  250.  
  251.             if qtMajor < MINIMUM_QT_MAJOR_VER:
  252.                 log.error("Incorrect version of Qt installed. Ver. 3.0.0 or greater required.")
  253.             else:
  254.                 #check version of PyQt
  255.                 try:
  256.                     pyqtVersion = qt.PYQT_VERSION_STR
  257.                 except AttributeError:
  258.                     pyqtVersion = qt.PYQT_VERSION
  259.  
  260.                 while pyqtVersion.count('.') < 2:
  261.                     pyqtVersion += '.0'
  262.  
  263.                 (maj_ver, min_ver, pat_ver) = pyqtVersion.split('.')
  264.  
  265.                 if pyqtVersion.find('snapshot') >= 0:
  266.                     log.error("A non-stable snapshot version of PyQt is installed (%s)." % pyqtVersion)
  267.                     num_errors += 1
  268.                 else:
  269.                     try:
  270.                         maj_ver = int(maj_ver)
  271.                         min_ver = int(min_ver)
  272.                         pat_ver = int(pat_ver)
  273.                     except ValueError:
  274.                         maj_ver, min_ver, pat_ver = 0, 0, 0
  275.  
  276.                     if maj_ver < MINIMUM_PYQT_MAJOR_VER or \
  277.                         (maj_ver == MINIMUM_PYQT_MAJOR_VER and min_ver < MINIMUM_PYQT_MINOR_VER):
  278.                         num_errors += 1
  279.                         log.error("HPLIP may not function properly with the version of PyQt that is installed (%d.%d.%d)." % (maj_ver, min_ver, pat_ver))
  280.                         log.error("Ver. %d.%d or greater required." % (MINIMUM_PYQT_MAJOR_VER, MINIMUM_PYQT_MINOR_VER))
  281.                     else:
  282.                         log.info("OK, version %d.%d installed." % (maj_ver, min_ver))
  283.             del qt
  284.  
  285.  
  286.     else:
  287.  
  288.         log.info()
  289.         log.info(log.bold("Checking PyQt 4.x version..."))
  290.  
  291.         # PyQt 4
  292.         try:
  293.             import PyQt4
  294.         except ImportError:
  295.             num_errors += 1
  296.             log.error("NOT FOUND OR FAILED TO LOAD!")
  297.         else:
  298.             from PyQt4 import QtCore
  299.             log.info("OK, version %s installed." % QtCore.PYQT_VERSION_STR)
  300.  
  301.  
  302. #    log.info()
  303. #    log.info(log.bold("Checking SIP version..."))
  304. #
  305. #    sip_ver = None
  306. #    try:
  307. #        import pyqtconfig
  308. #    except ImportError:
  309. #        pass
  310. #    else:
  311. #        sip_ver = pyqtconfig.Configuration().sip_version_str
  312. #
  313. #    if sip_ver is not None:
  314. #        log.info("OK, Version %s installed" % sip_ver)
  315. #    else:
  316. #        num_errors += 1
  317. #        log.error("SIP not installed or version not found.")
  318.  
  319.     log.info()
  320.     log.info(log.bold("Checking for CUPS..."))
  321.     cups_ok = True
  322.  
  323.     status, output = utils.run('lpstat -r')
  324.     if status == 0:
  325.         log.info("Status: %s" % output.strip())
  326.     else:
  327.         log.error("Status: (Not available. CUPS may not be installed or not running.)")
  328.         cups_ok = False
  329.         num_errors += 1
  330.  
  331.     if cups_ok:
  332.         status, output = utils.run('cups-config --version')
  333.         if status == 0:
  334.             log.info("Version: %s" % output.strip())
  335.         else:
  336.             log.error("Version: (Not available. CUPS may not be installed or not running.)")
  337.             cups_ok = False
  338.             num_errors += 1
  339.  
  340.     if cups_ok:
  341.         cups_conf = '/etc/cups/cupsd.conf'
  342.  
  343.         try:
  344.             f = file(cups_conf, 'r')
  345.         except (IOError, OSError):
  346.             log.warn("%s file not found or not accessible." % cups_conf)
  347.         else:
  348.             for l in f:
  349.                 m = pat_cups_error_log.match(l)
  350.                 if m is not None:
  351.                     level = m.group(1).lower()
  352.                     log.info("error_log is set to level: %s" % level)
  353.  
  354.                     #if level not in ('debug', 'debug2'):
  355.                         #log.note("For troubleshooting printing issues, it is best to have the CUPS 'LogLevel'")
  356.                         #log.note("set to 'debug'. To set the LogLevel to debug, edit the file %s (as root)," % cups_conf)
  357.                         #log.note("and change the line near the top of the file that begins with 'LogLevel' to read:")
  358.                         #log.note("LogLevel debug")
  359.                         #log.note("Save the file and then restart CUPS (see your OS/distro docs on how to restart CUPS).")
  360.                         #log.note("Now, when you print, helpful debug information will be saved to the file:")
  361.                         #log.note("/var/log/cups/error_log")
  362.                         #log.note("You can monitor this file by running this command in a console/shell:")
  363.                         #log.note("tail -f /var/log/cups/error_log")
  364.  
  365.                     break
  366.  
  367.  
  368.     log.info()
  369.  
  370.     log.info(log.bold("Checking for dbus/python-dbus..."))
  371.  
  372.     if dcheck.check_ps(['dbus-daemon']):
  373.         log.info("dbus daemon is running.")
  374.     else:
  375.         log.warn("dbus daemon is not running.")
  376.  
  377.     try:
  378.         import dbus
  379.         try:
  380.             log.info("python-dbus version: %s" % dbus.__version__)
  381.         except AttributeError:
  382.             try:
  383.                 log.info("python-dbus version: %s" % '.'.join([str(x) for x in dbus.version]))
  384.             except AttributeError:
  385.                 log.warn("python-dbus imported OK, but unknown version.")
  386.     except ImportError:
  387.         log.warn("python-dbus not installed.")
  388.  
  389.     log.info()
  390.  
  391.  
  392.     if time_flag == DEPENDENCY_RUN_AND_COMPILE_TIME:
  393.         tui.header("COMPILE AND RUNTIME DEPENDENCIES")
  394.         log.note("To check for compile-time only dependencies, re-run hp-check with the -c parameter (ie, hp-check -c).")
  395.         log.note("To check for run-time only dependencies, re-run hp-check with the -r parameter (ie, hp-check -r).")
  396.  
  397.     elif time_flag == DEPENDENCY_COMPILE_TIME:
  398.         tui.header("COMPILE TIME DEPENDENCIES")
  399.  
  400.     elif time_flag == DEPENDENCY_RUN_TIME:
  401.         tui.header("RUNTIME DEPENDENCIES")
  402.  
  403.     log.info()
  404.  
  405.     dd = core.dependencies.keys()
  406.     dd.sort()
  407.     for d in dd:
  408.         if (d == 'pyqt' and core.ui_toolkit != 'qt3') or \
  409.            (d == 'pyqt4' and core.ui_toolkit != 'qt4'):
  410.             continue
  411.  
  412.         log.debug("***")
  413.  
  414.         if time_flag == DEPENDENCY_RUN_AND_COMPILE_TIME or time_flag == core.dependencies[d][4]:
  415.  
  416.             log.info(log.bold("Checking for dependency: %s..." % core.dependencies[d][2]))
  417.  
  418.             if core.have_dependencies[d]:
  419.                 log.info("OK, found.")
  420.             else:
  421.                 num_errors += 1
  422.  
  423.                 if core.dependencies[d][4] == DEPENDENCY_RUN_AND_COMPILE_TIME:
  424.                     s = ''
  425.                 elif core.dependencies[d][4] == DEPENDENCY_COMPILE_TIME:
  426.                     s = '/COMPILE TIME ONLY'
  427.  
  428.                 elif core.dependencies[d][4] == DEPENDENCY_RUN_TIME:
  429.                     s = '/RUNTIME ONLY'
  430.  
  431.                 if core.dependencies[d][0]:
  432.                     log.error("NOT FOUND! This is a REQUIRED%s dependency. Please make sure that this dependency is installed before installing or running HPLIP." % s)
  433.                 else:
  434.                     log.warn("NOT FOUND! This is an OPTIONAL%s dependency. Some HPLIP functionality may not function properly." %s)
  435.  
  436.                 if core.distro_supported():
  437.                     packages_to_install, commands = core.get_dependency_data(d)
  438.  
  439.                     commands_to_run = []
  440.  
  441.                     if packages_to_install:
  442.                         package_mgr_cmd = core.get_distro_data('package_mgr_cmd')
  443.  
  444.                         if package_mgr_cmd:
  445.                             packages_to_install = ' '.join(packages_to_install)
  446.                             commands_to_run.append(utils.cat(package_mgr_cmd))
  447.  
  448.                     if commands:
  449.                         commands_to_run.extend(commands)
  450.  
  451.                     overall_commands_to_run.extend(commands_to_run)
  452.  
  453.                     if len(commands_to_run) == 1:
  454.                         log.info("To install this dependency, execute this command:")
  455.                         log.info(commands_to_run[0])
  456.  
  457.                     elif len(commands_to_run) > 1:
  458.                         log.info("To install this dependency, execute these commands:")
  459.                         for c in commands_to_run:
  460.                             log.info(c)
  461.  
  462.  
  463.             log.info()
  464.  
  465.     if time_flag in (DEPENDENCY_RUN_TIME, DEPENDENCY_RUN_AND_COMPILE_TIME):
  466.         tui.header("HPLIP INSTALLATION")
  467.  
  468.         scanning_enabled = utils.to_bool(sys_conf.get('configure', 'scanner-build', '0'))
  469.  
  470.         log.info()
  471.         log.info(log.bold("Currently installed HPLIP version..."))
  472.         v = sys_conf.get('hplip', 'version')
  473.         home = sys_conf.get('dirs', 'home')
  474.  
  475.         if v:
  476.             log.info("HPLIP %s currently installed in '%s'." % (v, home))
  477.  
  478.             log.info()
  479.             log.info(log.bold("Current contents of '/etc/hp/hplip.conf' file:"))
  480.             try:
  481.                 output = file('/etc/hp/hplip.conf', 'r').read()
  482.             except (IOError, OSError), e:
  483.                 log.error("Could not access file: %s" % e.strerror)
  484.             else:
  485.                 log.info(output)
  486.  
  487.             log.info()
  488.             log.info(log.bold("Current contents of '~/.hplip/hplip.conf' file:"))
  489.             try:
  490.                 output = file(os.path.expanduser('~/.hplip/hplip.conf'), 'r').read()
  491.             except (IOError, OSError), e:
  492.                 log.error("Could not access file: %s" % e.strerror)
  493.             else:
  494.                 log.info(output)
  495.  
  496.         else:
  497.             log.info("Not found.")
  498.  
  499.  
  500.         if device_avail:
  501.             if prop.par_build:
  502.                 tui.header("DISCOVERED PARALLEL DEVICES")
  503.  
  504.                 devices = device.probeDevices(['par'])
  505.  
  506.                 if devices:
  507.                     f = tui.Formatter()
  508.                     f.header = ("Device URI", "Model")
  509.  
  510.                     for d, dd in devices.items():
  511.                         f.add((d, dd[0]))
  512.  
  513.                     f.output()
  514.  
  515.                 else:
  516.                     log.info("No devices found.")
  517.  
  518.                     if not core.have_dependencies['ppdev']:
  519.                         log.error("'ppdev' kernel module not loaded.")
  520.  
  521.             if prop.usb_build:
  522.                 tui.header("DISCOVERED USB DEVICES")
  523.  
  524.                 devices = device.probeDevices(['usb'])
  525.  
  526.                 if devices:
  527.                     f = tui.Formatter()
  528.                     f.header = ("Device URI", "Model")
  529.  
  530.                     for d, dd in devices.items():
  531.                         f.add((d, dd[0]))
  532.  
  533.                     f.output()
  534.  
  535.                 else:
  536.                     log.info("No devices found.")
  537.  
  538.  
  539.         tui.header("INSTALLED CUPS PRINTER QUEUES")
  540.  
  541.         lpstat_pat = re.compile(r"""^device for (.*): (.*)""", re.IGNORECASE)
  542.  
  543.         status, output = utils.run('lpstat -v')
  544.         log.info()
  545.  
  546.         cups_printers = []
  547.         for p in output.splitlines():
  548.             try:
  549.                 match = lpstat_pat.search(p)
  550.                 printer_name = match.group(1)
  551.                 device_uri = match.group(2)
  552.                 cups_printers.append((printer_name, device_uri))
  553.             except AttributeError:
  554.                 pass
  555.  
  556.         log.debug(cups_printers)
  557.  
  558.         if cups_printers:
  559.             non_hp = False
  560.             for p in cups_printers:
  561.                 printer_name, device_uri = p
  562.                 try:
  563.                     back_end, is_hp, bus, model, serial, dev_file, host, port = \
  564.                         parseDeviceURI(device_uri)
  565.                 except Error:
  566.                     back_end, is_hp, bus, model, serial, dev_file, host, port = \
  567.                         '', False, '', '', '', '', '', 1
  568.  
  569.                 log.info(log.bold(printer_name))
  570.                 log.info(log.bold('-'*len(printer_name)))
  571.  
  572.                 x = "Unknown"
  573.                 if back_end == 'hpfax':
  574.                     x = "Fax"
  575.                 elif back_end == 'hp':
  576.                     x = "Printer"
  577.  
  578.                 log.info("Type: %s" % x)
  579.  
  580.                 if is_hp:
  581.                     x = 'Yes, using the %s: CUPS backend.' % back_end
  582.                 else:
  583.                     x = 'No, not using the hp: or hpfax: CUPS backend.'
  584.                     non_hp = True
  585.  
  586.                 log.info("Installed in HPLIP?: %s" % x)
  587.                 log.info("Device URI: %s" % device_uri)
  588.  
  589.                 ppd = os.path.join('/etc/cups/ppd', printer_name + '.ppd')
  590.  
  591.                 if os.path.exists(ppd):
  592.                     log.info("PPD: %s" % ppd)
  593.                     nickname_pat = re.compile(r'''\*NickName:\s*\"(.*)"''', re.MULTILINE)
  594.  
  595.                     f = file(ppd, 'r').read(4096)
  596.  
  597.                     try:
  598.                         desc = nickname_pat.search(f).group(1)
  599.                     except AttributeError:
  600.                         desc = ''
  601.  
  602.                     log.info("PPD Description: %s" % desc)
  603.  
  604.                     status, output = utils.run('lpstat -p%s' % printer_name)
  605.                     log.info("Printer status: %s" % output.replace("\n", ""))
  606.  
  607.                     if back_end == 'hpfax' and not 'HP Fax' in desc:
  608.                         num_errors += 1
  609.                         log.error("Incorrect PPD file for fax queue '%s'. Fax queues must use 'HP-Fax-hplip.ppd'." % printer_name)
  610.  
  611.                     elif back_end == 'hp' and 'HP Fax' in desc:
  612.                         num_errors += 1
  613.                         log.error("Incorrect PPD file for a print queue '%s'. Print queues must not use 'HP-Fax-hplip.ppd'." % printer_name)
  614.  
  615.                     elif back_end not in ('hp', 'hpfax'):
  616.                         log.warn("Printer is not HPLIP installed. Printers must use the hp: or hpfax: CUPS backend to function in HPLIP.")
  617.                         num_errors += 1
  618.  
  619.                 if device_avail and is_hp:
  620.                     d = None
  621.                     try:
  622.                         try:
  623.                             d = device.Device(device_uri)
  624.                         except Error:
  625.                             log.error("Device initialization failed.")
  626.                             continue
  627.  
  628.                         plugin = d.mq.get('plugin', PLUGIN_NONE)
  629.                         if plugin in (PLUGIN_REQUIRED, PLUGIN_OPTIONAL):
  630.  
  631.                             if core.check_for_plugin():
  632.                                 if plugin == PLUGIN_REQUIRED:
  633.                                     log.info("Required plug-in status: Installed")
  634.                                 else:
  635.                                     log.info("Optional plug-in status: Installed")
  636.                             else:
  637.                                 num_errors += 1
  638.  
  639.                                 if plugin == PLUGIN_REQUIRED:
  640.                                     log.error("Required plug-in status: Not installed")
  641.                                 else:
  642.                                     log.warn("Optional plug-in status: Not installed")
  643.  
  644.  
  645.                         if bus in ('par', 'usb'):
  646.                             try:
  647.                                 d.open()
  648.                             except Error, e:
  649.                                 log.error(e.msg)
  650.                                 deviceid = ''
  651.                             else:
  652.                                 deviceid = d.getDeviceID()
  653.                                 log.debug(deviceid)
  654.  
  655.                             if not deviceid:
  656.                                 #log.error("Communication status: Failed")
  657.                                 num_errors += 1
  658.                             else:
  659.                                 log.info("Communication status: Good")
  660.  
  661.                         elif bus == 'net':
  662.                             try:
  663.                                 error_code, deviceid = d.getPML(pml.OID_DEVICE_ID)
  664.                             except Error:
  665.                                 #log.error("Communication with device failed.")
  666.                                 error_code = pml.ERROR_COMMAND_EXECUTION
  667.  
  668.                             if error_code > pml.ERROR_MAX_OK:
  669.                                 #log.error("Communication status: Failed")
  670.                                 num_errors += 1
  671.                             else:
  672.                                 log.info("Communication status: Good")
  673.  
  674.                     finally:
  675.                         if d is not None:
  676.                             d.close()
  677.  
  678.                     log.info()
  679.  
  680.  
  681.  
  682.         else:
  683.             log.warn("No queues found.")
  684.  
  685.         if scanning_enabled:
  686.             tui.header("SANE CONFIGURATION")
  687.             log.info(log.bold("'hpaio' in '/etc/sane.d/dll.conf'..."))
  688.             try:
  689.                 f = file('/etc/sane.d/dll.conf', 'r')
  690.             except IOError:
  691.                 log.error("'/etc/sane.d/dll.conf' not found. Is SANE installed?")
  692.                 num_errors += 1
  693.             else:
  694.                 found = False
  695.                 for line in f:
  696.                     if 'hpaio' in line:
  697.                         found = True
  698.  
  699.         # Debian/ Ubuntu place hpaio in /etc/sane.d/dll.d/hplip, so lets check there too
  700.  
  701.         if not found:
  702.             log.info(log.bold("'hpaio' in '/etc/sane.d/dll.d/hplip'..."))
  703.             try:
  704.                        f = file('/etc/sane.d/dll.d/hplip', 'r')
  705.                     except IOError:
  706.                        log.error("'/etc/sane.d/dll.d/hplip' not found.")
  707.                        num_errors += 1
  708.                     else:
  709.                         found = False
  710.                         for line in f:
  711.                             if 'hpaio' in line:
  712.                                 found = True
  713.  
  714.                 if found:
  715.                     log.info("OK, found. SANE backend 'hpaio' is properly set up.")
  716.                 else:
  717.                     num_errors += 1
  718.                     log.error("Not found. SANE backend 'hpaio' NOT properly setup (needs to be added to /etc/sane.d/dll.conf).")
  719.  
  720.                 log.info()
  721.                 log.info(log.bold("Checking output of 'scanimage -L'..."))
  722.                 if utils.which('scanimage'):
  723.                     status, output = utils.run("scanimage -L")
  724.                     log.info(output)
  725.                 else:
  726.                     log.error("scanimage not found.")
  727.  
  728.         tui.header("PYTHON EXTENSIONS")
  729.  
  730.         log.info(log.bold("Checking 'cupsext' CUPS extension..."))
  731.         try:
  732.             import cupsext
  733.         except ImportError:
  734.             num_errors += 1
  735.             log.error("NOT FOUND OR FAILED TO LOAD! Please reinstall HPLIP and check for the proper installation of cupsext.")
  736.         else:
  737.             log.info("OK, found.")
  738.  
  739.         log.info()
  740.         log.info(log.bold("Checking 'pcardext' Photocard extension..."))
  741.         try:
  742.             import pcardext
  743.         except ImportError:
  744.             num_errors += 1
  745.             log.error("NOT FOUND OR FAILED TO LOAD! Please reinstall HPLIP and check for the proper installation of pcardext.")
  746.         else:
  747.             log.info("OK, found.")
  748.  
  749.         log.info()
  750.         log.info(log.bold("Checking 'hpmudext' I/O extension..."))
  751.         try:
  752.             import hpmudext
  753.             hpmudext_avail = True
  754.         except ImportError:
  755.             hpmudext_avail = False
  756.             num_errors += 1
  757.             log.error("NOT FOUND OR FAILED TO LOAD! Please reinstall HPLIP and check for the proper installation of hpmudext.")
  758.         else:
  759.             log.info("OK, found.")
  760.  
  761.         if scanning_enabled:
  762.             log.info()
  763.             log.info(log.bold("Checking 'scanext' SANE scanning extension..."))
  764.             try:
  765.                 import scanext
  766.             except ImportError:
  767.                 num_errors += 1
  768.                 log.error("NOT FOUND OR FAILED TO LOAD! Please reinstall HPLIP and check for the proper installation of scanext.")
  769.             else:
  770.                 log.info("OK, found.")
  771.  
  772.                 log.info()
  773.  
  774.         tui.header("USB I/O SETUP")
  775.  
  776.         if hpmudext_avail:
  777.             lsusb = utils.which('lsusb')
  778.             if lsusb:
  779.                 log.info()
  780.                 log.info(log.bold("Checking for permissions of USB attached printers..."))
  781.                 lsusb = os.path.join(lsusb, 'lsusb')
  782.                 status, output = utils.run("%s -d03f0:" % lsusb)
  783.  
  784.                 lsusb_pat = re.compile("""^Bus\s([0-9a-fA-F]{3,3})\sDevice\s([0-9a-fA-F]{3,3}):\sID\s([0-9a-fA-F]{4,4}):([0-9a-fA-F]{4,4})(.*)""", re.IGNORECASE)
  785.                 log.debug(output)
  786.  
  787.                 for o in output.splitlines():
  788.                     ok = True
  789.                     match = lsusb_pat.search(o)
  790.  
  791.                     if match is not None:
  792.                         bus, device, vid, pid, mfg = match.groups()
  793.                         log.info("\nHP Device 0x%x at %s:%s: " % (int(pid, 16), bus, device))
  794.                         result_code, deviceuri = hpmudext.make_usb_uri(bus, device)
  795.  
  796.                         if result_code == hpmudext.HPMUD_R_OK:
  797.                             log.info("    Device URI: %s" %  deviceuri)
  798.                         else:
  799.                             log.warn("    Device URI: (Makeuri FAILED)")
  800.  
  801.                         devnode = os.path.join("/", "dev", "bus", "usb", bus, device)
  802.  
  803.                         if not os.path.exists(devnode):
  804.                             devnode = os.path.join("/", "proc", "bus", "usb", bus, device)
  805.  
  806.                         if os.path.exists(devnode):
  807.                             log.info("    Device node: %s" % devnode)
  808.  
  809.                             st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid, \
  810.                                 st_size, st_atime, st_mtime, st_ctime = \
  811.                                 os.stat(devnode)
  812.  
  813.                             log.info("    Mode: 0%o" % (st_mode & 0777))
  814.  
  815.                             getfacl = utils.which('getfacl')
  816.                             if getfacl:
  817.                                 getfacl = os.path.join(getfacl, "getfacl")
  818.  
  819.                                 status, output = utils.run("%s %s" % (getfacl, devnode))
  820.  
  821.                                 log.info(output)
  822.  
  823.  
  824.     tui.header("SUMMARY")
  825.  
  826.     if num_errors:
  827.         if num_errors == 1:
  828.             log.error("1 error or warning.")
  829.         else:
  830.             log.error("%d errors and/or warnings." % num_errors)
  831.  
  832.         if overall_commands_to_run:
  833.             log.info()
  834.             log.info(log.bold("Summary of needed commands to run to satisfy missing dependencies:"))
  835.             for c in overall_commands_to_run:
  836.                 log.info(c)
  837.  
  838.         log.info()
  839.         log.info("Please refer to the installation instructions at:")
  840.         log.info("http://hplip.sourceforge.net/install/index.html\n")
  841.  
  842.     else:
  843.         log.info(log.green("No errors or warnings."))
  844.  
  845. except KeyboardInterrupt:
  846.     log.error("User exit")
  847.  
  848. log.info()
  849. log.info("Done.")
  850.  
  851.